package dao.Impl;

import dao.GenericDao;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import util.Pagination;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;

public class GenericDaoImpl <T extends Serializable,ID extends Number> implements GenericDao<T,ID> {
    private SqlSession sqlSession;
    @Autowired
    public void setSqlSession(SqlSession sqlSession) {
        this.sqlSession = sqlSession;
    }
    private String nameSpace;
    GenericDaoImpl(){
        ParameterizedType parameterizedType = (ParameterizedType) getClass().getGenericSuperclass();
        Class<T> clazz = (Class<T>) parameterizedType.getActualTypeArguments()[0];
        nameSpace = StringUtils.uncapitalize(clazz.getSimpleName());
    }
    private String getSqlStatu(String sqlId){
        return nameSpace.concat(".").concat(sqlId);
    };
    @Override
    public void create(T t) {
        sqlSession.insert(getSqlStatu("create"),t);
    }

    @Override
    public T queryById(ID id) {
        return sqlSession.selectOne(getSqlStatu("queryById"),id);
    }

    @Override
    public void modify(T t) {
        sqlSession.update(getSqlStatu("modify"),t);
    }

    @Override
    public void remove(ID id) {
        sqlSession.delete(getSqlStatu("remove"),id);
    }

    @Override
    public List<T> queryAll() {
        return sqlSession.selectList(getSqlStatu("queryAll"));
    }

    @Override
    public void create(String sqlId, Object parameter) {
        sqlSession.insert(getSqlStatu(sqlId),parameter);
    }

    @Override
    public T queryOne(String sqlId, Object parameter) {
        return sqlSession.selectOne(getSqlStatu(sqlId),parameter);
    }

    @Override
    public void modify(String sqlId, Object parameter) {
        sqlSession.update(getSqlStatu(sqlId),parameter);
    }

    @Override
    public List<T> queryList(String sqlId, Object parameter) {
        return sqlSession.selectList(getSqlStatu(sqlId),parameter);
    }

    @Override
    public Object query(String sqlId, Object parameter) {
        return sqlSession.selectOne(getSqlStatu(sqlId),parameter);
    }






    private Pagination<T> getPagination(String queryId, Object parameter, int currentPage){
        int totalRows = sqlSession.selectList(getSqlStatu(queryId),parameter).size();

        int pageSize = 3;
        int totalPages =(int) Math.ceil(totalRows/(double)pageSize);
        RowBounds rowBounds = new RowBounds(pageSize*(currentPage-1),pageSize);
        List<T> list = sqlSession.selectList(getSqlStatu(queryId),parameter,rowBounds);

        return new Pagination<>(queryId,list,totalRows,pageSize,totalPages,currentPage);
    }
    @Override
    public Pagination<T> queryAll(int currentPage) {
        return getPagination("queryAll",null,currentPage);
    }

    @Override
    public Pagination<T> query(String sqlId, Object parameter, int currentPage) {
        return getPagination(sqlId, parameter, currentPage);
    }
}
